package util;

import java.math.BigDecimal;
import java.math.RoundingMode;

/**
 * Lagrange插值法有关的函数
 */
public class LagrangeSet {
    /**
     * 拉格朗日基本多项式
     * @param x 插值法输入的自变量
     * @param xi 自变量的集合
     * @param xj 特定点的值
     * @param tagJ 特定点的下标
     * @return 基本多项式的值
     * @throws Exception 特殊点的下标不满足基本多项式的要求的时候，throw exception
     */
    public static BigDecimal larBasicPoly(BigDecimal x,BigDecimal[] xi,BigDecimal xj,int tagJ)throws Exception{
        if(tagJ<0||tagJ>=xi.length){
            throw new Exception("tagJ的值不符合拉格朗日基本多项式的要求/tagJ doesn't match restriction of Lagrange polynomial");
        }
        BigDecimal result=BigDecimal.ONE;
        BigDecimal dividend;
        BigDecimal divisor;
        for (int i = 0; i < xi.length; i++) {
            if(i!=tagJ){
                dividend=x.subtract(xi[i]);
                divisor=xj.subtract(xi[i]);
                result=result.multiply(dividend.divide(divisor));
            }
        }
        return result;
    }

    /**
     * 拉格朗日插值法接口
     * @param x 插值法中古的自变量
     * @param xi x坐标的集合
     * @param yi 对应x的y值
     * @return 插值法计算的结果
     * @throws Exception x的集合和y的集合规模不同时 throw exception
     */
    public static BigDecimal larInterpolation(BigDecimal x,BigDecimal[] xi,BigDecimal[] yi ) throws  Exception{
        //数据合规性判定
        if(xi.length!=yi.length){
            throw new Exception("两数组规模不同/two array have different size");
        }
        BigDecimal result=BigDecimal.ZERO;
        BigDecimal pValue;
        for (int i = 0; i < xi.length; i++) {
            pValue=larBasicPoly(x,xi,xi[i],i);
            result=result.add(pValue.multiply(yi[i]));
        }
        return result;
    }
}
